package com.goldenlight.fvms.manager.filter;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.goldenlight.fvms.manager.entity.EmployFreeApply;
import com.goldenlight.fvms.manager.entity.FreeApply;
import com.goldenlight.fvms.manager.idgenerator.service.IdService;
import com.goldenlight.fvms.manager.service.EmployFreeApplyService;
import com.goldenlight.fvms.manager.service.FreeApplyService;
import com.goldenlight.fvms.manager.utils.CommonUtils;
import com.goldenlight.fvms.manager.utils.ExcelUtils;
import com.goldenlight.fvms.manager.websocket.ExcelUploadWebSocketServer;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class EmployFreeCarApplyFilter implements Filter {
    @Override
    public void doFilter(Request request, Response response, FilterChain filterChain) {
        Map<String, Object> req = request.getData();
        Integer type = (Integer) req.get("type");
        if (type == 5) {
            Map<String, Object> result = doRequest(request, response, filterChain);
            filterChain.doFilter(request, response, filterChain);
            if((Integer)result.get("code")==530){//有重复记录
                response.setResponse(com.goldenlight.fvms.manager.vo.Response.build(530, "repeat", result));
            }else if((Integer)result.get("code")==200){//成功
                response.setResponse(com.goldenlight.fvms.manager.vo.Response.build(200, "success", result));
            }else if((Integer)result.get("code")==540){//车牌重复，姓名不重复
                response.setResponse(com.goldenlight.fvms.manager.vo.Response.build(540, "warn", result));
            }else if((Integer)result.get("code")==550){
                response.setResponse(com.goldenlight.fvms.manager.vo.Response.build(550, "warn", result));
            }else if((Integer)result.get("code")==510){
                response.setResponse(com.goldenlight.fvms.manager.vo.Response.build(510, "warn", result));
            }
        }else {
            filterChain.doFilter(request, response, filterChain);
        }

    }


    private Map<String, Object> doRequest(Request request, Response response, FilterChain filterChain) {
        /**
         * 1.获取参数
         */
        Map<String, Object> req = request.getData();
        Logger logger = (Logger) req.get("logger");
        String uuid = (String) req.get("uuid");
        String buildVersion= (String) req.get("buildVersion");
        Integer type = (Integer) req.get("type");

        IdService idService = (IdService) req.get("idService");
        FreeApplyService freeApplyService = (FreeApplyService) req.get("parentService");
        EmployFreeApplyService employFreeApplyService = (EmployFreeApplyService) req.get("service");
        MultipartFile file = (MultipartFile) req.get("file");

        /**
         * 2 获取上一次导入的版本号
         */
        String oldVersion = getOldVersion(employFreeApplyService);


        Map<String, Object> result = new HashMap<String, Object>();//返回前台界面数据}
//        final List<String> companys = GlobalCont.list;//规定可以申请免费车的公司

        List<EmployFreeApply> listExcel = ExcelUtils.importExcel(file, 1, 2, EmployFreeApply.class);//导入excel信息
        logger.info("excel 初始导入：{}", listExcel);

        List<EmployFreeApply> filterList = listExcel;
        String applicantUnit = filterList.get(0).getApplicantUnit();
        if (listExcel.size() <= 0 || StringUtils.isEmpty(applicantUnit)) {
            result.put("code", 550);
            return result;
        }


        if(isExistBuildVersion(buildVersion, freeApplyService)) {
            result.put("code", 510);
            return result;
        }
        String currVersion = buildVersion ;
        if (filterList.size() > 0) {
            if (dealData(logger, uuid, buildVersion, type, idService, freeApplyService, employFreeApplyService, oldVersion, result, filterList, applicantUnit, currVersion))
                return result;
        } else {
            result.put("outCompanys", listExcel);//不在申请公司内
            result.put("code", 550);
        }
        return result;
    }

    /**
     * 判断传入的版本号是否已经存在
     * @param buildVersion
     * @param freeApplyService
     * @return
     */
    private boolean isExistBuildVersion(String buildVersion, IService freeApplyService) {
        return null!=freeApplyService.getOne(new QueryWrapper<FreeApply>().lambda().eq(FreeApply::getBuildVersion, buildVersion));
    }

    private boolean dealData(Logger logger, String uuid, String buildVersion, Integer type, IdService idService, FreeApplyService freeApplyService, EmployFreeApplyService employFreeApplyService, String oldVersion, Map<String, Object> result, List<EmployFreeApply> filterList, String applicantUnit, String currVersion) {
        //筛选出存在的才进行去重

        Map<String, List<EmployFreeApply>> collect = filterList.stream().parallel()
                .filter(item->!StringUtils.isEmpty(item.getCarNum()) && !StringUtils.isEmpty(item.getApplicantName()) && !StringUtils.isEmpty(item.getCarBussType()))
                .collect(Collectors.groupingBy(EmployFreeApply::getJudeCondition));
        List<EmployFreeApply> reList = new ArrayList();//存储筛选出重复的车牌号、申请人姓名、业务类型
        List<EmployFreeApply> dealList = new ArrayList();//存储重复的车牌号和重复申请人姓名
        List<EmployFreeApply> repeatList = new ArrayList<>();//存储重复的车牌号和不重复申请人姓名
        List<EmployFreeApply> resultLis = new ArrayList<>();//车重复
        List<EmployFreeApply> nameList = new ArrayList<>();//人重复的

        getReListAndResultList(collect, reList, resultLis);


        List<EmployFreeApply> norepeatList = new ArrayList<>();

        dealRepeatList(dealList, repeatList, resultLis, nameList, norepeatList);

        if (reList.size() > 0) {
            result.put("code",530);
            result.put("reList", reList);
            return true;
        }

        CollectInfo collectInfo = new CollectInfo();

        Map<String, Object> conditionMap = new HashMap<>();


        collectInfo.setOldVersion(oldVersion);
        conditionMap.put("buildVersion", oldVersion);
        int count = employFreeApplyService.count(new QueryWrapper<EmployFreeApply>().lambda().eq(EmployFreeApply::getBuildVersion, oldVersion));
        collectInfo.total(StringUtils.isEmpty(oldVersion) ? 0 : count);//原有总条数
        conditionMap.put("carBussType", "新增");
        collectInfo.newTotal(StringUtils.isEmpty(oldVersion) ? 0 : employFreeApplyService.qryCount(conditionMap));//原有总新增条数
        conditionMap.put("carBussType", "已办理");
        collectInfo.dealTotal(StringUtils.isEmpty(oldVersion) ? 0 : employFreeApplyService.qryCount(conditionMap));//原有总新增条数conditionMap.put("carBussType", "新增");
        conditionMap.put("carBussType", "取消");
        collectInfo.cancelTotal(StringUtils.isEmpty(oldVersion) ? 0 : employFreeApplyService.qryCount(conditionMap));//原有总新增条数conditionMap.put("carBussType", "新增");

        if (repeatList.size() > 0) {
            dealRepeatData(logger, uuid, idService, freeApplyService, employFreeApplyService, currVersion, dealList, repeatList, norepeatList);
        }else {
            dealData(idService, freeApplyService, employFreeApplyService, currVersion, dealList, repeatList, norepeatList);
        }
        collectInfo.totalCurrent(employFreeApplyService.count(new QueryWrapper<EmployFreeApply>().lambda().eq(EmployFreeApply::getApplicantUnit, applicantUnit).eq(EmployFreeApply::getBuildVersion, currVersion)));//原有总条数
        conditionMap.put("buildVersion", currVersion);
        conditionMap.put("carBussType", "新增");
        collectInfo.newTotalCurrent(employFreeApplyService.qryCount(conditionMap));//原有总新增条数
        conditionMap.put("carBussType", "已办理");
        collectInfo.dealTotalCurrent(employFreeApplyService.qryCount(conditionMap));//原有总新增条数conditionMap.put("carBussType", "新增");
        conditionMap.put("carBussType", "取消");
        collectInfo.cancelTotalCurrent(employFreeApplyService.qryCount(conditionMap));//原有总新增条数conditionMap.put("carBussType", "新增");

        /**
         * add 20190611
         * 导入类型
         */
        collectInfo.setSelectType(type);
        collectInfo.setBuildVersion(buildVersion);
        result.put("cllectInfo", Lists.newArrayList(collectInfo));

        result.put("code", 200);
        return false;
    }

    private void dealData(IdService idService, FreeApplyService freeApplyService, EmployFreeApplyService employFreeApplyService, String currVersion, List<EmployFreeApply> dealList, List<EmployFreeApply> repeatList, List<EmployFreeApply> norepeatList) {
        cancleImportInfo(idService, freeApplyService, employFreeApplyService, currVersion, dealList);
        cancleImportInfo(idService, freeApplyService, employFreeApplyService, currVersion, repeatList);
        cancleImportInfo(idService, freeApplyService, employFreeApplyService, currVersion, norepeatList);
    }

    private void dealRepeatData(Logger logger, String uuid, IdService idService, FreeApplyService freeApplyService, EmployFreeApplyService employFreeApplyService, String currVersion, List<EmployFreeApply> dealList, List<EmployFreeApply> repeatList, List<EmployFreeApply> norepeatList) {
        RepeatListInfo reInfo = new RepeatListInfo("540", repeatList, null);
        Map<String, Object> reMap = new HashMap<>();
        reMap.put("isRepeat", "540");
        reMap.put("reList", repeatList);
        String jsonString = JSON.toJSONString(reMap);
        logger.info("websocket server send relist:{}", jsonString);
        //返回车牌重复姓名不重复列表 resMap
        ExcelUploadWebSocketServer.sendMessage(jsonString, uuid);
        logger.info("geted state:---------------------");
        //获取再次请求的状态
        dealWebsocketInfo(logger, idService, freeApplyService, employFreeApplyService, currVersion, dealList, repeatList, norepeatList);
    }

    private void dealWebsocketInfo(Logger logger, IdService idService, FreeApplyService freeApplyService, EmployFreeApplyService employFreeApplyService, String currVersion, List<EmployFreeApply> dealList, List<EmployFreeApply> repeatList, List<EmployFreeApply> norepeatList) {
        String state = ExcelUploadWebSocketServer.getState();
        ExcelUploadWebSocketServer.setState("");
        logger.info("geted state:{}", state);

        if ("ok".equals(state)) {
            dealData(idService, freeApplyService, employFreeApplyService, currVersion, dealList, repeatList, norepeatList);
        } else {
            //取消导入
            cancleImportInfo(idService, freeApplyService, employFreeApplyService, currVersion, norepeatList);
        }
    }

    private void cancleImportInfo(IdService idService, FreeApplyService freeApplyService, EmployFreeApplyService employFreeApplyService, String currVersion, List<EmployFreeApply> norepeatList) {
        norepeatList.stream().parallel().forEach(item -> {
            item.setBuildVersion(currVersion);

            item.setApplyId(idService.genId());
            FreeApply freeApply = CommonUtils.convert(item, FreeApply.class);
            freeApply.setTypeCode("5");
            freeApply.setApplyUnit(item.getApplicantUnit());
            freeApplyService.save(freeApply);

            employFreeApplyService.save(item);
        });
    }

    private String getOldVersion(EmployFreeApplyService employFreeApplyService) {
        QueryWrapper<EmployFreeApply> oldVersionQuery = new QueryWrapper<>();
        oldVersionQuery.lambda().orderByDesc(EmployFreeApply::getTimeStamp);
        List<EmployFreeApply> oldList = employFreeApplyService.list(oldVersionQuery);
        return oldList.isEmpty() ? "" : oldList.get(0).getBuildVersion();
    }

    private void dealRepeatList(List<EmployFreeApply> dealList, List<EmployFreeApply> repeatList, List<EmployFreeApply> resultLis, List<EmployFreeApply> nameList, List<EmployFreeApply> norepeatList) {
        Map<String, List<EmployFreeApply>> collectCar = resultLis.stream().parallel().collect(Collectors.groupingBy(EmployFreeApply::getCarNum));//根据车牌号和申请人姓名晒选,车牌号重复，人不重复的
        collectCar.forEach((ke, val) -> {
            if (val.size() > 1) {//车牌号重复的
                val.forEach(item -> {
                            nameList.add(item);
                        }
                );

            } else {
                val.forEach(item -> {
                            norepeatList.add(item);
                        }
                );
            }
        });

        Map<String, List<EmployFreeApply>> collectName = nameList.stream().collect(Collectors.groupingBy(EmployFreeApply::getApplicantName));
        collectName.forEach((key, value) -> {
            if (value.size() > 1) { //车牌号重复，人姓名也重复的
                value.parallelStream().forEach(item1 -> {
                    dealList.add(item1);
                });
            } else {//车牌号不重复，人姓名不重复的
                value.parallelStream().forEach(item1 -> {
                    repeatList.add(item1);
                });
                ;
            }
        });
    }

    private static void getReListAndResultList(Map<String, List<EmployFreeApply>> collect, List<EmployFreeApply> reList, List<EmployFreeApply> resultLis) {
        collect.forEach((k, v) -> {
            if (v.size() > 1) {
                v.parallelStream().forEach(item -> {
                    if (null != k) {
                        reList.add(item);
                    }
                });
            } else if (v.size() == 1) {
                v.parallelStream().forEach(item -> {
                    resultLis.add(item);
                });

            }
        });
    }

}
